package com.bikes.mileagetracker.service

import android.app.Service
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.content.ServiceConnection
import android.os.Binder
import android.os.IBinder
import android.os.IInterface
import android.util.Log
import com.bikes.mileagetracker.MileageTrackerApplication
import com.bikes.mileagetracker.orm.BaseDataBaseHelper
import com.bikes.mileagetracker.entity.LocationEntity
import com.bikes.mileagetracker.entity.TrackingEntity
import com.bikes.mileagetracker.entity.UserEntity
import com.bikes.mileagetracker.utils.SharedPreferencesUtils
import org.apache.commons.lang3.StringUtils

interface IPersistenceService {

    companion object {
        const val SHARED_PREFERENCES_NAME_USER = "USER"
        const val SHARED_PREFERENCES_KEY_LATEST = "LATEST"
    }

    fun loadLatestUser(): UserEntity?

    fun updateLatestUser(user: UserEntity)

    fun loadUserList(): List<UserEntity>

    fun saveUser(user: UserEntity)

    fun removeUser(user: UserEntity)

    fun findUserById(userId: String): UserEntity?

    fun findUserByName(username: String): UserEntity?

    fun loadUserTrackings(userId: String): List<TrackingEntity>

    fun saveTracking(tracking: TrackingEntity)

    fun loadUserLocations(userId: String): List<LocationEntity>

    fun saveLocations(location: LocationEntity)

}


class PersistenceImpl : Binder(), IInterface, IPersistenceService {

    private val userEntityHelper = object: BaseDataBaseHelper<UserEntity>(){}
    private val trackingEntityHelper = object: BaseDataBaseHelper<TrackingEntity>(){}
    private val locationEntityHelper = object: BaseDataBaseHelper<LocationEntity>(){}

    override fun loadLatestUser(): UserEntity? {

        val userId=SharedPreferencesUtils .getStringPrivate(
                MileageTrackerApplication.getCurrentApplication(),
                IPersistenceService.SHARED_PREFERENCES_NAME_USER,
                IPersistenceService.SHARED_PREFERENCES_KEY_LATEST,
                "")

        return if(userId is String && StringUtils.isNotBlank(userId)){
             findUserById(userId)
        }else {
             null
        }
    }


    override fun updateLatestUser(user: UserEntity){
        SharedPreferencesUtils.putStringPrivateA(MileageTrackerApplication.getCurrentApplication(),"USER", "LATEST", user.id)
    }

    override fun loadUserList(): List<UserEntity> {
        return userEntityHelper.byCondition("status=0",arrayOf(),"", "", "updateTm")
    }

    override fun saveUser(user: UserEntity) {
        user.updateTm = System.currentTimeMillis()
        userEntityHelper.save(user)
    }

    override fun removeUser(user: UserEntity) {
        val dbuser = userEntityHelper.byId(user.id)
        if(dbuser is UserEntity) {
            dbuser.updateTm =  System.currentTimeMillis()
            dbuser.status = -1
            userEntityHelper.save(dbuser)
        }
    }

    override fun findUserById(userId: String): UserEntity? {
        return userEntityHelper.byId(userId)
    }

    override fun findUserByName(username: String): UserEntity? {
        return userEntityHelper.byCondition("username=?",arrayOf(username),"", "", "").getOrNull(0)
    }

    override fun loadUserTrackings(userId: String): List<TrackingEntity> {
        return trackingEntityHelper.byCondition("userId=?", arrayOf(userId),"", "", "updateTm desc")
    }

    override fun saveTracking(tracking: TrackingEntity) {
        tracking.updateTm = System.currentTimeMillis()
        trackingEntityHelper.save(tracking)
        Log.v("console", "save tracking: from: ${tracking.startAddress} to: ${tracking.endAddress} miles: ${tracking.miles}")
    }

    override fun loadUserLocations(userId: String): List<LocationEntity> {
        return locationEntityHelper.byCondition("userId=?", arrayOf(userId), "","","userId, trackingId, updateTm")
    }

    override fun saveLocations(location: LocationEntity) {
        location.updateTm = System.currentTimeMillis()
        locationEntityHelper.save(location)
        Log.v("console", "save location: ${location.userId} ${location.trackingId} [${location.longitude}, ${location.latitude}]")
    }

    override fun asBinder(): IBinder {
        return this
    }


}

class PersistenceService : Service() {

    override fun onBind(intent: Intent): IBinder? {
        return PersistenceImpl()
    }




    companion object {
        @JvmStatic
        var service:IPersistenceService? = null


        @JvmStatic
        fun bind(ctx: Context){
            val intent = Intent(ctx, PersistenceService::class.java)
            ctx.bindService(intent, object: ServiceConnection {
                override fun onServiceDisconnected(name: ComponentName?) {
                    if(service is IPersistenceService){
                        service = null
                    }
                }

                override fun onServiceConnected(name: ComponentName?, binder: IBinder?) {
                    if(binder is IPersistenceService){
                        PersistenceService.service = binder
                    }else{
                        ctx.unbindService(this)
                    }
                }
            },Context.BIND_WAIVE_PRIORITY or Context.BIND_AUTO_CREATE or Context.BIND_NOT_FOREGROUND)
        }
    }
}
